home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / unixcpio.gz / unixnet.cpio / pathname.c < prev    next >
C/C++ Source or Header  |  1994-07-11  |  3KB  |  121 lines

  1. #include "global.h"
  2.  
  3. /* Given a working directory and an arbitrary pathname, resolve them into
  4.  * an absolute pathname. Memory is allocated for the result, which
  5.  * the caller must free
  6.  */
  7. char *
  8. pathname(cd,path)
  9. char *cd;    /* Current working directory */
  10. char *path;    /* Pathname argument */
  11. {
  12.     register char *buf;
  13. #if    (defined(MSDOS) || defined(ATARI_ST))
  14.     register char *cp;
  15.     char *cdtmp,*pathtmp;
  16. #endif
  17.  
  18.     if(cd == NULLCHAR || path == NULLCHAR)
  19.         return NULLCHAR;
  20. #if    (defined(MSDOS) || defined(ATARI_ST))
  21.     /* Make temporary copies of cd and path
  22.      * with all \'s translated to /'s
  23.     */
  24.     pathtmp = malloc((unsigned)strlen(path)+1);
  25.     strcpy(pathtmp,path);
  26.     path = pathtmp;
  27.     if((cp = path) != NULLCHAR){
  28.         while((cp = index(cp,'\\')) != NULLCHAR)
  29.             *cp = '/';
  30.     }
  31.     cdtmp = malloc((unsigned)strlen(cd)+1);
  32.     strcpy(cdtmp,cd);
  33.     cd = cdtmp;
  34.     if((cp = cd) != NULLCHAR){
  35.         while((cp = index(cp,'\\')) != NULLCHAR)
  36.             *cp = '/';
  37.     }
  38. #endif
  39.     /* Strip any leading white space on args */
  40.     while(*cd == ' ' || *cd == '\t')
  41.         cd++;
  42.     while(*path == ' ' || *path == '\t')
  43.         path++;
  44.  
  45.     /* Allocate and initialize output buffer; user must free */
  46.     buf = malloc((unsigned)strlen(cd) + strlen(path) + 10);    /* fudge factor */
  47.     buf[0] = '\0';
  48.  
  49.     /* Interpret path relative to cd only if it doesn't begin with "/" */
  50.     if(path[0] != '/')
  51.         crunch(buf,cd);
  52.  
  53.     crunch(buf,path);
  54.  
  55.     /* Special case: null final path means the root directory */
  56.     if(buf[0] == '\0'){
  57.         buf[0] = '/';
  58.         buf[1] = '\0';
  59.     }
  60.  
  61. #if    (defined(MSDOS) || defined(ATARI_ST))
  62.     /* Translate all /'s back to \'s and free temp copies of args */
  63.     if((cp = buf) != NULLCHAR){
  64.         while((cp = index(cp,'/')) != NULLCHAR)
  65.             *cp = '\\';
  66.     }
  67.     free(cdtmp);
  68.     free(pathtmp);
  69. #endif
  70.     return buf;
  71. }
  72.  
  73. /* Process a path name string, starting with and adding to
  74.  * the existing buffer
  75.  */
  76. static
  77. crunch(buf,path)
  78. char *buf;
  79. register char *path;
  80. {
  81.     register char *cp;
  82.     
  83.  
  84.     cp = buf + strlen(buf);    /* Start write at end of current buffer */
  85.     
  86.     /* Now start crunching the pathname argument */
  87.     for(;;){
  88.         /* Strip leading /'s; one will be written later */
  89.         while(*path == '/')
  90.             path++;
  91.         if(*path == '\0')
  92.             break;        /* no more, all done */
  93.         /* Look for parent directory references, either at the end
  94.          * of the path or imbedded in it
  95.          */
  96.         if(strcmp(path,"..") == 0 || strncmp(path,"../",3) == 0){
  97.             /* Hop up a level */
  98.             if((cp = rindex(buf,'/')) == NULLCHAR)
  99.                 cp = buf;    /* Don't back up beyond root */
  100.             *cp = '\0';        /* In case there's another .. */
  101.             path += 2;        /* Skip ".." */
  102.             while(*path == '/')    /* Skip one or more slashes */
  103.                 path++;
  104.         /* Look for current directory references, either at the end
  105.          * of the path or imbedded in it
  106.          */
  107.         } else if(strcmp(path,".") == 0 || strncmp(path,"./",2) == 0){
  108.             /* "no op" */
  109.             path++;            /* Skip "." */
  110.             while(*path == '/')    /* Skip one or more slashes */
  111.                 path++;
  112.         } else {
  113.             /* Ordinary name, copy up to next '/' or end of path */
  114.             *cp++ = '/';
  115.             while(*path != '/' && *path != '\0')
  116.                 *cp++ = *path++;
  117.         }
  118.     }
  119.     *cp++ = '\0';
  120. }
  121.